﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Insteon;
using Interfaces;

namespace Mesne
{
    public class Executor : IExecutor
    {
        private object writeLock = new object();
        private System.Timers.Timer commandActivator;
        private ConcurrentQueue<ICommand> commandQueue;

        public event Action<string, string> ResultReturned;

        public Executor()
        {
            commandQueue = new ConcurrentQueue<ICommand>();
            commandActivator = new System.Timers.Timer(AppSettings.Executor.CommandActivationCycle)
            {
                AutoReset = true,
                Enabled = true
            };
            commandActivator.Elapsed += commandActivator_Elapsed;
            commandActivator.Start();
        }

        public void Add(ICommand command)
        {
            if (command != null)
            {
                if (commandQueue != null)
                {
                    commandQueue.Enqueue(command);
                }
            }
        }

        void commandActivator_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ICommand command;
            if (commandQueue.TryDequeue(out command))
            {
                try
                {
                    Serial.Port.DiscardInBuffer();
                    if (Serial.Port.IsOpen == false)
                    {
                        Serial.Port.Open();
                    }
                    lock (writeLock)
                    {
                        Serial.Port.Write(command.ByteArray, 0, command.Count);
                    }



                    while (Serial.Port.BytesToRead < 9)
                    {
                        System.Threading.Thread.Sleep(50);
                    }
                    byte[] bytes = new byte[9];
                    Serial.Port.Read(bytes, 0, bytes.Length);
                    string receipt = BitConverter.ToString(bytes);
                    if (ResultReturned != null)
                    {
                        if (receipt.EndsWith("06"))
                        {
                            ResultReturned(command.DeviceID, bytes[7].ToString());
                        }
                        else
                        {
                            ResultReturned(command.DeviceID, bytes[7].ToString());
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.IO.StreamWriter writer = new System.IO.StreamWriter(@"C:\mesne\mesne.log");
                    writer.WriteLine(ex.ToString());
                    writer.Close();
                }
            }
        }
    }
}
